#include "simpleupdate.h"
#include "enetwork.h"
#include "dbapp.h"
#include <QDate>
#include <QJsonDocument>
#include <QJsonObject>
#include "machineutil.h"
#include "mylogger.h"
#include "dbdata.h"

using namespace ns_yht;

SimpleUpdate::SimpleUpdate()
{
}

SimpleUpdate::~SimpleUpdate()
{
}

SimpleUpdate *SimpleUpdate::instance()
{
    static SimpleUpdate *instance = nullptr;
    if (instance == nullptr)
    {
        instance = new SimpleUpdate();
    }
    return instance;
}

void SimpleUpdate::setShipType(int shipType)
{
    m_shipType = shipType;
}

void SimpleUpdate::startRiskArea()
{
    m_code = "Risk-Area";
    m_name = "风险区域";
    if (GLOG)
        GLOG->info("requestRiskArea start......");
    QNetworkReply *reply = ENetwork::Get("http://restapi.ehanghai.cn/xxyc-api/system/prod/version_manage/v1/get_box_area?type=" + QString::number(m_shipType), "", "", true);
    connect(reply, &QNetworkReply::finished, this, [=]
            { requestRiskAreaFinished(reply); });
}

void SimpleUpdate::requestRiskAreaFinished(QNetworkReply *reply)
{
    if (GLOG)
        GLOG->info("requestRiskArea finished. ");
    if (ENetwork::checkReplyError(reply))
    {
        if (GLOG)
            GLOG->info("requestRiskArea Finished 1. code:{} name:{}  result: false", m_code.toStdString(), m_name.toStdString());
        // postUpdateLog(false);
        emit updateFinished(false);
        return;
    }
    const QJsonDocument &jsonDocument = QJsonDocument::fromJson(reply->readAll());
    reply->deleteLater();

    if (!jsonDocument.isNull())
    {
        const QJsonObject &rootObj = jsonDocument.object();
        if (rootObj.value("errorcode").toInt() == 0)
        {
            auto item = rootObj.value("result").toObject();
            QVector<ModelRiskArea> areaList;
#if 0 // 原来0-7
            const auto &wreckArray = item.value("WRECK").toArray();
            setModelArray(areaList, RiskAreaType::wreck, wreckArray);
            const auto &reefs = item.value("REEF").toArray();
            setModelArray(areaList, RiskAreaType::reef, reefs);
            const auto &ship_routings = item.value("SHIP_ROUTING").toArray();
            setModelArray(areaList, RiskAreaType::ship_routing, ship_routings);
            const auto &ship_crashes = item.value("SHIP_CRASH").toArray();
            setModelArray(areaList, RiskAreaType::ship_crash, ship_crashes);
            const auto &port = item.value("PORT").toArray();
            setModelArray(areaList, RiskAreaType::port, port);
            const auto &bridge = item.value("BRIDGE").toArray();
            setModelArray(areaList, RiskAreaType::bridge, bridge);
            const auto &pipe = item.value("PIPE").toArray();
            setModelArray(areaList, RiskAreaType::pipe, pipe);
            const auto &airline = item.value("AIRLINE").toArray();
            setModelArray(areaList, RiskAreaType::airline, airline);
#endif

#if 0
            const auto &array00 = item.value("WRECK").toArray();
            setModelArray(areaList, RiskAreaType::wreck, array00);
            const auto &array01 = item.value("OBSTRUCTIVE_OBJECT").toArray();
            setModelArray(areaList, RiskAreaType::obstructive_object, array01);
            const auto &array02 = item.value("REEF").toArray();
            setModelArray(areaList, RiskAreaType::reef, array02);
            const auto &array03 = item.value("SHALLOW_WATER").toArray();
            setModelArray(areaList, RiskAreaType::shallow_water, array03);
            const auto &array04 = item.value("HIGH_INCIDENCE_AREA").toArray();
            setModelArray(areaList, RiskAreaType::high_incidence_area, array04);
            const auto &array05 = item.value("TRAFFIC_SEPARATION_AREA").toArray();
            setModelArray(areaList, RiskAreaType::traffic_separation_area, array05);
            const auto &array06 = item.value("WARNING_AREA").toArray();
            setModelArray(areaList, RiskAreaType::warning_area, array06);
            const auto &array07 = item.value("PROHIBITED_AREA").toArray();
            setModelArray(areaList, RiskAreaType::prohibited_area, array07);
            const auto &array08 = item.value("PORT").toArray();
            setModelArray(areaList, RiskAreaType::port, array08);
            const auto &array09 = item.value("SEA_CROSSINGS").toArray();
            setModelArray(areaList, RiskAreaType::sea_crossings, array09);
            const auto &array10 = item.value("SUBSEA_PIPELINE").toArray();
            setModelArray(areaList, RiskAreaType::subsea_pipeline, array10);
            const auto &array11 = item.value("FERRY_AREA").toArray();
            setModelArray(areaList, RiskAreaType::ferry_area, array11);
            const auto &array12 = item.value("MARITIME_INSPECTION_AREA").toArray();
            setModelArray(areaList, RiskAreaType::maritime_inspection_area, array12);
            const auto &array13 = item.value("BREEDING_AREA").toArray();
            setModelArray(areaList, RiskAreaType::breeding_area, array13);
            const auto &array14 = item.value("NONAVIGATION_ZONE").toArray();
            setModelArray(areaList, RiskAreaType::nonavigation_zone, array14);
            const auto &array15 = item.value("VTS_REPORT_LINE").toArray();
            setModelArray(areaList, RiskAreaType::vts_report_line, array15);
            const auto &array16 = item.value("BOUNDARY_OF_THE_CONTROL_AREA").toArray();
            setModelArray(areaList, RiskAreaType::boundary_of_the_control_area, array16);
            const auto &array17 = item.value("CROSS_DRIVING_AREA").toArray();
            setModelArray(areaList, RiskAreaType::cross_driving_area, array17);
            const auto &array18 = item.value("RAPIDS_AREA").toArray();
            setModelArray(areaList, RiskAreaType::rapids_area, array18);
            const auto &array19 = item.value("ANCHORAGE").toArray();
            setModelArray(areaList, RiskAreaType::anchorage, array19);
            const auto &array20 = item.value("OFFSHORE_WIND_POWER").toArray();
            setModelArray(areaList, RiskAreaType::offshore_wind_power, array20);
            const auto &array21 = item.value("NO_CROSSING_ZONE").toArray();
            setModelArray(areaList, RiskAreaType::no_crossing_zone, array21);
#endif

            const QStringList keyList = {"WRECK", "OBSTRUCTIVE_OBJECT", "REEF", "SHALLOW_WATER", "HIGH_INCIDENCE_AREA",
                                         "TRAFFIC_SEPARATION_AREA", "WARNING_AREA", "PROHIBITED_AREA", "PORT", "SEA_CROSSINGS",
                                         "SUBSEA_PIPELINE", "FERRY_AREA", "MARITIME_INSPECTION_AREA", "BREEDING_AREA", "NONAVIGATION_ZONE",
                                         "VTS_REPORT_LINE", "BOUNDARY_OF_THE_CONTROL_AREA", "CROSS_DRIVING_AREA", "RAPIDS_AREA", "ANCHORAGE",
                                         "OFFSHORE_W IND_POWER", "NO_CROSSING_ZONE"};
            for (int i = 0; i < keyList.size(); i++)
            {
                const auto &array = item.value(keyList.at(i)).toArray();
                setModelArray(areaList, i, array);
            }

            if (!DBDATA->saveRiskArea(areaList))
            {
                if (GLOG)
                    GLOG->info("requestRiskArea Finished 2. code:{} name:{}  result: false", m_code.toStdString(), m_name.toStdString());
                emit updateFinished(false);
                return;
            }
        }
        else
        {
            if (GLOG)
                GLOG->info("requestRiskArea Finished 3. code:{} name:{}  reason:{} result: false", m_code.toStdString(), m_name.toStdString(), rootObj.value("reason").toString().toStdString());
            //             postUpdateLog(false);
            emit updateFinished(0);
            return;
        }
    }

    if (GLOG)
        GLOG->info("requestRiskArea Finished. code:{} name:{}  result: true", m_code.toStdString(), m_name.toStdString());
    //     postUpdateLog(1);
    emit updateFinished(true);
}

void SimpleUpdate::setModelArray(QVector<ModelRiskArea> &riskAreas, int atype, const QJsonArray &array)
{
    foreach (const auto &item, array)
    {
        const auto &object = item.toArray();
        ModelRiskArea area;
        area.type = atype;
        area.name = object.at(1).toString();
        area.geom = object.at(2).toString();
        area.extension = object.at(3).toString();
        area.radius = object.at(4).toDouble();
        riskAreas.append(area);
    }
}

void SimpleUpdate::postUpdateLog(int result)
{
    QJsonObject obj;
    obj.insert("machineCode", MachineUtil::machineCode());
    obj.insert("softwareCode", m_code);
    obj.insert("result", result);

    QNetworkReply *reply = ENetwork::PostWithJson(QJsonDocument(obj).toJson(), "http://restapi.ehanghai.cn/xxyc-api/updateLog", {}, {}, true);
    if (reply)
        connect(reply, &QNetworkReply::finished, this, [=]
                { onUpdateLogFinished(reply); });
}

void SimpleUpdate::onUpdateLogFinished(QNetworkReply *reply)
{
    if (ENetwork::checkReplyError(reply))
    {
        return;
    }
    const QJsonDocument &jsonDocument = QJsonDocument::fromJson(reply->readAll());
    reply->deleteLater();

    if (!jsonDocument.isNull())
    {
        const QJsonObject &rootObj = jsonDocument.object();
        if (rootObj.value("success").toBool())
        {
            if (GLOG)
                GLOG->info("SimpleUpdate updateLog Finished - ok");
        }
        else
        {
            if (GLOG)
                GLOG->info("SimpleUpdate updateLog Finished - failed - {}", rootObj.value("errorMsg").toString().toStdString());
        }
    }
}
